import subprocess
from pathlib import Path


class AudioConverter:
    """
    通用音频转WAV工具类（依赖ffmpeg）
    支持格式：MP3, WebM, WAV等ffmpeg支持的音频格式
    功能：
    1. 单文件转换（自动识别输入格式）
    2. 批量转换目录下所有音频文件
    3. 自定义采样率/声道数
    """

    def __init__(self, ffmpeg_path="ffmpeg"):
        """
        初始化检查ffmpeg是否可用
        :param ffmpeg_path: ffmpeg可执行文件路径（默认从系统PATH查找）
        """
        self.ffmpeg_path = self._check_ffmpeg(ffmpeg_path)
        self.supported_input_formats = ['.mp3', '.webm', '.wav', '.ogg', '.flac']  # 可扩展

    def _check_ffmpeg(self, ffmpeg_path):
        """验证ffmpeg是否安装"""
        try:
            subprocess.run([ffmpeg_path, "-version"],
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE,
                           check=True)
            return ffmpeg_path
        except (subprocess.CalledProcessError, FileNotFoundError):
            raise EnvironmentError(
                f"未找到ffmpeg，请安装并添加到系统PATH，或手动指定路径。\n"
                f"官网下载：https://ffmpeg.org/"
            )

    def _is_supported_format(self, file_path):
        """检查文件格式是否受支持"""
        file_path = Path(file_path)
        return file_path.suffix.lower() in self.supported_input_formats

    def convert(
            self,
            input_path,
            output_path=None,
            sample_rate=16000,
            channels=1,
            overwrite=False,
    ):
        """
        单文件转换（支持多种输入格式）
        :param input_path: 输入音频路径（支持MP3/WebM等）
        :param output_path: 输出WAV路径（默认同目录下同名文件）
        :param sample_rate: 输出采样率（默认16kHz，适合语音）
        :param channels: 声道数（默认单声道）
        :param overwrite: 是否覆盖已存在文件
        :return: 转换后的WAV路径
        """
        input_path = Path(input_path)
        if not input_path.exists():
            raise FileNotFoundError(f"输入文件不存在: {input_path}")

        if not self._is_supported_format(input_path):
            raise ValueError(
                f"不支持的文件格式: {input_path.suffix}\n"
                f"支持格式: {', '.join(self.supported_input_formats)}"
            )

        # 设置默认输出路径
        if output_path is None:
            output_path = get_unique_output_path(input_path,"../temp_audio_wav")

        output_path = Path(output_path)  # 确保转换为Path对象
        # 检查输出文件是否已存在
        if output_path.exists() and not overwrite:
            raise FileExistsError(f"输出文件已存在: {output_path}")

        # 执行转换命令（通用音频转WAV）
        command = [
            self.ffmpeg_path,
            "-i", str(input_path),
            "-ar", str(sample_rate),
            "-ac", str(channels),
            "-y" if overwrite else "-n",
            str(output_path),
        ]

        try:
            subprocess.run(command, check=True, stderr=subprocess.PIPE)
            print(f"转换成功: {input_path} -> {output_path}")
            return output_path
        except subprocess.CalledProcessError as e:
            error_msg = e.stderr.decode('utf-8') if e.stderr else str(e)
            raise RuntimeError(f"转换失败: {error_msg}")

    def convert_dir(
            self,
            input_dir,
            output_dir=None,
            sample_rate=16000,
            channels=1,
            overwrite=False,
            extensions=None
    ):
        """
        批量转换目录下所有音频文件
        :param input_dir: 输入目录
        :param output_dir: 输出目录（默认同输入目录）
        :param extensions: 要转换的文件扩展名列表（如['.mp3', '.webm']），默认使用类定义的支持格式
        :return: 成功转换的文件列表
        """
        input_dir = Path(input_dir)
        if not input_dir.is_dir():
            raise NotADirectoryError(f"输入路径不是目录: {input_dir}")

        # 设置默认输出目录
        output_dir = Path(output_dir) if output_dir else input_dir
        output_dir.mkdir(parents=True, exist_ok=True)

        # 确定要处理的文件扩展名
        target_extensions = extensions if extensions is not None else self.supported_input_formats

        converted_files = []
        for ext in target_extensions:
            for audio_file in input_dir.glob(f"*{ext}"):
                output_path = output_dir / f"{audio_file.stem}.wav"
                try:
                    self.convert(
                        audio_file,
                        output_path,
                        sample_rate,
                        channels,
                        overwrite,
                    )
                    converted_files.append(output_path)
                except Exception as e:
                    print(f"跳过 {audio_file}，错误: {str(e)}")

        return converted_files


from datetime import datetime
import os

# 自定义输出路径
def get_unique_output_path(input_path, output_dir):
    """
    生成带时间戳的唯一输出路径
    :param input_path: 原始文件路径
    :param output_dir: 自定义输出目录（可选）
    :return: Path对象
    """
    input_path = Path(input_path)

    output_dir = Path(output_dir)

    # 创建目录（如果不存在）
    output_dir.mkdir(parents=True, exist_ok=True)

    # 生成带时间戳的文件名
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    output_filename = f"{input_path.stem}_{timestamp}.wav"

    return output_dir / output_filename

# 使用示例
if __name__ == "__main__":
    # 初始化转换器
    converter = AudioConverter()

    # 示例1：单文件转换（MP3）
    converter.convert(r"C:\Users\ZX\Desktop\d7452fd1-2c75-4ddb-ba2c-087f271f395b.MP3")

    # # 示例2：单文件转换（WebM）
    # converter.convert("input.webm", "output.wav")
    #
    # # 示例3：批量转换目录下所有MP3和WebM文件
    # converter.convert_dir(
    #     input_dir="audio_files",
    #     extensions=['.mp3', '.webm']  # 明确指定要转换的格式
    # )